<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>错误报告</title>
<link media="all" rel="stylesheet" type="text/css" href="styles/03e73060321a0a848018724a6c83de7f-theme-base.css" />
<link media="all" rel="stylesheet" type="text/css" href="styles/03e73060321a0a848018724a6c83de7f-theme-medium.css" />

 </head>
 <body class="docs"><div class="navbar navbar-fixed-top">
  <div class="navbar-inner clearfix">
    <ul class="nav" style="width: 100%">
      <li style="float: left;"><a href="security.database.sql-injection.html">« SQL 注入</a></li>
      <li style="float: right;"><a href="security.variables.html">用户提交的数据 »</a></li>
    </ul>
  </div>
</div>
<div id="breadcrumbs" class="clearfix">
  <ul class="breadcrumbs-container">
    <li><a href="index.html">PHP Manual</a></li>
    <li><a href="security.html">安全</a></li>
    <li>错误报告</li>
  </ul>
</div>
<div id="layout">
  <div id="layout-content"><div id="security.errors" class="chapter">
   <h1>错误报告</h1>

   <p class="para">
    对于 PHP 的安全性来说错误报告是一把双刃剑。一方面可以提高安全性，另一方面又有害。
   </p>
   <p class="para">
    攻击系统时经常使用的手法就是输入不正确的数据，然后查看错误提示的类型及上下文。这样做有利于攻击者收集服务器的信息以便寻找弱点。比如说，如果一个攻击者知道了一个页面所基于的表单信息，那么他就会尝试修改变量：
    <div class="example" id="example-441">
     <p><strong>示例 #1 用自定义的 HTML 页面攻击变量</strong></p>
     <div class="example-contents">
<div class="htmlcode"><pre class="htmlcode">&lt;form method=&quot;post&quot; action=&quot;attacktarget?username=badfoo&amp;amp;password=badfoo&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;username&quot; value=&quot;badfoo&quot; /&gt;
&lt;input type=&quot;hidden&quot; name=&quot;password&quot; value=&quot;badfoo&quot; /&gt;
&lt;/form&gt;</pre>
</div>
     </div>

    </div>
   </p>
   <p class="para">
    通常 PHP
    所返回的错误提示都能帮助开发者调试程序，它会提出哪个文件的哪些函数或代码出错，并指出错误发生的在文件的第几行，这些就是
    PHP 本身所能给出的信息。很多 PHP 开发者会使用
    <span class="function"><a href="function.show-source.html" class="function">show_source()</a></span>、<span class="function"><a href="function.highlight-string.html" class="function">highlight_string()</a></span>
    或者 <span class="function"><a href="function.highlight-file.html" class="function">highlight_file()</a></span>
    函数来调试代码，但是在正式运行的网站中，这种做法可能会暴露出隐藏的变量、未检查的语法和其它的可能危及系统安全的信息。在运行一些具有内部调试处理的程序，或者使用通用调试技术是很危险的。如果让攻击者确定了程序是使用了哪种具体的调试技术，他们会尝试发送变量来打开调试功能：
    <div class="example" id="example-442">
     <p><strong>示例 #2 利用变量打开调式功能</strong></p>
     <div class="example-contents">
<div class="htmlcode"><pre class="htmlcode">&lt;form method=&quot;post&quot; action=&quot;attacktarget?errors=Y&amp;amp;showerrors=1&amp;amp;debug=1&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;errors&quot; value=&quot;Y&quot; /&gt;
&lt;input type=&quot;hidden&quot; name=&quot;showerrors&quot; value=&quot;1&quot; /&gt;
&lt;input type=&quot;hidden&quot; name=&quot;debug&quot; value=&quot;1&quot; /&gt;
&lt;/form&gt;</pre>
</div>
     </div>

    </div>
   </p>
   <p class="para">
    不管错误处理机制如何，可以探测系统错误的能力会给攻击者提供更多信息。
   </p>
   <p class="para">
    比如说，PHP 的独有的错误提示风格可以说明系统在运行 PHP。如果攻击者在寻找一个 .html
    为页面，想知道其后台的技术（为了寻找系统弱点），他们就会把错误的数据提交上去，然后就有可以得知系统是基于
    PHP 的了。
   </p>
   <p class="para">
    一个函数错误就可能暴露系统正在使用的数据库，或者为攻击者提供有关网页、程序或设计方面的有用信息。攻击者往往会顺藤摸瓜地找到开放的数据库端口，以及页面上某些 bug
    或弱点等。比如说，攻击者可以一些不正常的数据使程序出错，来探测脚本中认证的顺序（通过错误提示的行号数字）以及脚本中其它位置可能泄露的信息。
   </p>
   <p class="para">
    一个文件系统或者 PHP 的错误就会暴露 web
    服务器具有什么权限，以及文件在服务器上的组织结构。开发者自己写的错误代码会加剧此问题，导致泄漏了原本隐藏的信息。
   </p>
   <p class="para">
    有三个常用的办法处理这些问题。第一个是彻底地检查所有函数，并尝试弥补大多数错误。第二个是对在线系统彻底关闭错误报告。第三个是使用
    PHP 自定义的错误处理函数创建自己的错误处理机制。根据不同的安全策略，三种方法可能都适用。
   </p>
   <p class="para">
    一个能提前阻止这个问题发生的方法就是利用
    <span class="function"><a href="function.error-reporting.html" class="function">error_reporting()</a></span> 来帮助使代码更安全并发现变量使用的危险之处。在发布程序之前，先打开
    <strong><code>E_ALL</code></strong> 测试代码，可以帮你很快找到变量使用不当的地方。一旦准备正式发布，就应该把
    <span class="function"><a href="function.error-reporting.html" class="function">error_reporting()</a></span> 的参数设为 0 来彻底关闭错误报告或者把 <var class="filename">php.ini</var>
    中的 <code class="literal">display_errors</code> 设为 off
    来关闭所有的错误显示以将代码隔绝于探测。当然，如果要迟一些再这样做，就不要忘记打开 ini 文件内的
    <code class="literal">log_errors</code> 选项，并通过 <code class="literal">error_log</code> 指定用于记录错误信息的文件。
    <div class="example" id="example-443">
     <p><strong>示例 #3 用 E_ALL 来查找危险的变量</strong></p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">$username</span><span style="color: #007700">)&nbsp;{&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Not&nbsp;initialized&nbsp;or&nbsp;checked&nbsp;before&nbsp;usage<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$good_login&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />}<br />if&nbsp;(</span><span style="color: #0000BB">$good_login&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">)&nbsp;{&nbsp;</span><span style="color: #FF8000">//&nbsp;If&nbsp;above&nbsp;test&nbsp;fails,&nbsp;not&nbsp;initialized&nbsp;or&nbsp;checked&nbsp;before&nbsp;usage<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">readfile&nbsp;</span><span style="color: #007700">(</span><span style="color: #DD0000">"/highly/sensitive/data/index.html"</span><span style="color: #007700">);<br />}<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</code></div>
     </div>

    </div>
   </p>
  </div>
</div></div></body></html>